:: ffmpeg -i output.mp4 -vf select='eq(pict_type\,I)' -vsync vfr  -s 1920*1080   keyframe-%02d.png
:: jpg 大小小于png ,在bat 中 % 需要写2边才能转义

:: 关于 fps_mode vfr 参数的意义  https://blog.csdn.net/ternence_hsu/article/details/101276939

:: 官方文档 https://ffmpeg.org/ffmpeg-all.html#Advanced-options

::-vsync parameter (global)
::-fps_mode[:stream_specifier] parameter (output,per-stream)
::Set video sync method / framerate mode. vsync is applied to all output video streams but can be overridden for a stream by setting fps_mode. vsync is deprecated and will be removed in the future.
::
::For compatibility reasons some of the values for vsync can be specified as numbers (shown in parentheses in the following table).
::
::passthrough (0)
::Each frame is passed with its timestamp from the demuxer to the muxer.
::
::cfr (1)
::Frames will be duplicated and dropped to achieve exactly the requested constant frame rate.
::
::vfr (2)
::Frames are passed through with their timestamp or dropped so as to prevent 2 frames from having the same timestamp.
::
::auto (-1)
::Chooses between cfr and vfr depending on muxer capabilities. This is the default method.
::
::Note that the timestamps may be further modified by the muxer, after this. For example, in the case that the format option avoid_negative_ts is enabled.
::
::With -map you can select from which stream the timestamps should be taken. You can leave either video or audio unchanged and sync the remaining stream(s) to the unchanged one.

:: -vsync vfr 选项确保提取的视频帧与原始视频帧的时间戳一致

::ffmpeg -i xue.mp4 -vf "select='eq(pict_type\,I)'" -fps_mode vfr  -vsync vfr  -f image2 output_%%07d.jpg

ffmpeg -i b.mp4 -vf "select='eq(pict_type\,I)',showinfo" -fps_mode vfr -frame_pts true output_%%07d.jpg
:: 提取时间戳 一行一个
ffmpeg -i b.mp4 -vf "select='eq(pict_type\,I)',showinfo" -fps_mode vfr -f null - 2>&1 | grep 'pts_time' > timestamps.txt

ffmpeg -i b.mp4 -vf "select='eq(pict_type\,I)',showinfo" -vsync vfr -f null - 2>&1 | awk -F 'pts_time:' '/pts_time/ {printf "keyframe_%04d.png %.5f\n", NR, $2}' > timestamps.txt



FFmpeg 提供了 select 过滤器，可以用来检测场景变化，从而提取场景间差异较大的帧。你可以通过设置阈值来选择具有显著变化的帧：
这个命令中的 gt(scene,0.4) 过滤器会选择场景变化大于阈值的帧（0.4 是一个例子，可以根据需要调整）。showinfo 选项会在输出中包含有关每一帧的信息，你可以用来检查哪些帧被选择了。

ffmpeg -i xue.mp4 -vf "select='gt(scene,0.4)',showinfo" -fps_mode vfr scene_change_%04d.png



要仅使用 FFmpeg 截取视频中差异较大的图片，你可以结合 FFmpeg 的视频分析功能和一些自定义过滤器。虽然 FFmpeg 本身不提供直接的帧差异分析功能，但你可以使用 FFmpeg 提取帧和应用滤镜来间接实现类似的效果。

以下是一个方法，利用 FFmpeg 的 select 滤镜来选择那些有显著变化的帧：

1. 提取关键帧
视频中通常包含一些关键帧（关键帧是那些完全编码的帧，其他帧可能只记录差异）。我们可以使用 FFmpeg 提取这些关键帧，这些帧之间通常会有较大的差异。

bash
复制代码
ffmpeg -i input_video.mp4 -vf "select='eq(pict_type,I)'" -vsync vfr keyframes_%04d.png
这个命令会提取视频中的所有关键帧（I帧），并将其保存为 keyframes_0001.png、keyframes_0002.png 等。-vsync vfr 选项确保提取的视频帧与原始视频帧的时间戳一致。

2. 利用 FFmpeg 的场景检测
FFmpeg 提供了 select 过滤器，可以用来检测场景变化，从而提取场景间差异较大的帧。你可以通过设置阈值来选择具有显著变化的帧：

bash
复制代码
ffmpeg -i input_video.mp4 -vf "select='gt(scene,0.4)',showinfo" -vsync vfr scene_change_%04d.png
这个命令中的 gt(scene,0.4) 过滤器会选择场景变化大于阈值的帧（0.4 是一个例子，可以根据需要调整）。showinfo 选项会在输出中包含有关每一帧的信息，你可以用来检查哪些帧被选择了。

3. 结合使用场景检测和关键帧提取
为了确保选择的是差异明显的帧，可能需要结合使用场景检测和关键帧提取。可以先提取场景变化明显的帧，然后从中提取关键帧。

bash
复制代码
# 提取场景变化明显的帧
ffmpeg -i input_video.mp4 -vf "select='gt(scene,0.4)'" -vsync vfr temp_%04d.png

# 从场景变化明显的帧中提取关键帧
ffmpeg -i input_video.mp4 -vf "select='eq(pict_type,I)'" -vsync vfr -f image2 -i temp_%04d.png significant_frames_%04d.png
这个组合命令首先提取场景变化明显的帧，然后从中提取关键帧。

4. 清理临时文件
在提取完关键帧或场景变化帧后，别忘了删除临时生成的帧文件：

bash
复制代码
rm temp_*.png
总结
提取关键帧：使用 select='eq(pict_type,I)' 提取关键帧。
场景检测：使用 select='gt(scene,0.4)' 检测场景变化。
结合使用：根据需要提取场景变化明显的帧，然后从中选择关键帧。
这些方法可以帮助你提取视频中变化较大的帧。根据视频的特点，你可能需要调整阈值和选择合适的参数。



在 FFmpeg 中，除了提取关键帧和使用场景检测，你还可以利用一些高级的滤镜和选项来进一步精细化地控制帧提取，以下是几种其他方法：

1. 使用 fps 选项和 select 滤镜
你可以使用 fps 选项与 select 滤镜的结合来选择某些间隔的帧，这可以帮助你减少帧的数量以更好地识别有显著变化的帧。

bash
复制代码
ffmpeg -i input_video.mp4 -vf "select='not(mod(n,30))',fps=1" -vsync vfr sampled_frames_%04d.png
这个命令将每隔 30 帧提取一帧，并将其保存为 sampled_frames_0001.png 等。你可以根据需要调整 mod(n,30) 的参数。

2. 使用 minterpolate 滤镜
minterpolate 滤镜可以生成中间帧，用于增强帧之间的视觉对比，从而帮助你检测差异较大的帧：

bash
复制代码
ffmpeg -i input_video.mp4 -vf "minterpolate='fps=10'" interpolated_frames_%04d.png
这个命令生成每秒 10 帧的视频（插值），然后你可以比较这些插值帧来发现变化较大的帧。

ffmpeg -i input_video.mp4 -vf "minterpolate='fps=60'" interpolated_%04d.png
这个命令将视频帧率提高到每秒 60 帧，这样你可以通过比较生成的插值帧来分析运动。请根据需要调整 fps 的值。


3. 使用 metadata 选项分析
FFmpeg 可以使用 metadata 选项输出每帧的时间戳和其他信息。通过分析这些信息，你可以发现变化较大的帧。例如：

bash
复制代码
ffmpeg -i input_video.mp4 -vf "select='gt(scene,0.4)',showinfo" -vsync vfr -f image2 -y scene_change_%04d.png


4. 使用 fps 选项结合 select 滤镜
你可以结合 fps 选项与 select 滤镜来提取具有显著场景变化的帧：

bash
复制代码
ffmpeg -i input_video.mp4 -vf "fps=1,select='gt(scene,0.3)'" -vsync vfr scene_changes_%04d.png
在这个例子中，fps=1 设置为每秒提取一帧，而 select='gt(scene,0.3)' 将选择变化大于 0.3 的帧。调整阈值 0.3 可以改变选择的敏感度。

5. 使用 select 和 metadata 的组合
你可以使用 metadata 提取更多的信息，并结合 select 滤镜进一步分析帧：

bash
复制代码
ffmpeg -i input_video.mp4 -vf "select='gt(scene,0.4)',metadata=print" -vsync vfr -f image2 scene_changes_%04d.png
在这个命令中，metadata=print 选项会将有关每一帧的元数据打印到输出中，这样你可以进一步分析帧之间的差异。

6. 检测运动
可以使用 motion 滤镜检测帧之间的运动来选择变化较大的帧：

bash
复制代码
ffmpeg -i input_video.mp4 -vf "motion" -vsync vfr motion_frames_%04d.png
这会输出检测到运动的帧，你可以根据运动量来选择差异较大的帧。

7. 检测和比较颜色直方图
如果你更关注颜色变化，可以使用 histogram 滤镜：

bash
复制代码
ffmpeg -i input_video.mp4 -vf "select='gt(scene,0.5)',histogram=display_mode=stack" -vsync vfr histogram_%04d.png
这个命令提取变化明显的帧并计算颜色直方图。

总结
fps 和 select 组合：控制帧提取速率和选择显著变化的帧。
minterpolate 滤镜：生成中间帧以增强视觉对比。
metadata 分析：分析帧的时间戳和其他信息。
motion 滤镜：检测帧之间的运动。
histogram 滤镜：分析颜色变化。
这些方法提供了不同的手段来分析和提取视频中的显著变化帧。根据实际需求，你可以选择合适的方法或组合几种方法来实现你的目标。